package com.glodon.zhuanli.system.service;

import com.glodon.framework.common.encrypt.PasswordEncoder;
import com.glodon.zhuanli.common.MapConverter;
import com.glodon.zhuanli.common.Maps2;
import com.glodon.zhuanli.common.service.ZhuanliBaseServiceImpl;
import com.glodon.zhuanli.system.dao.SysUserDao;
import com.glodon.zhuanli.system.entity.SysUser;
import com.google.common.collect.Maps;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.*;

@Service
public class SysUserService extends ZhuanliBaseServiceImpl<SysUser , SysUserDao> {

	/**
	 * 企业管理员默认绑定的角色id
	 */
	public static final String COMPANY_USER_ROLEID = "3274525331105069812" ;

	/**
	 * 用户属于企业负责人的type属性值
	 */
	public static final String COMPANY_RESPONSIBLE = "user_identity_main" ;

	/**
	 * 默认的密码
	 */
	public static final String DEFAULT_PASSWORD = "123qwe" ;
	
	/**
	 * 查询条件表达式
	 */
	private LinkedHashMap<String, String> expressionMap = new LinkedHashMap<String , String>(){
			{
				put("code" , "code:EQ:queryexist") ;
				put("mobile" , "OR:mobile:EQ:queryexist") ;

				put("name" , "name:LIKE") ;
				put("type" , "type:LIKE") ;
				put("companyId" , "companyId:EQ") ;
				put("ids" , "id:IN") ;
				put("source" , "source:EQ") ;

				//路径查询
				put("orgpath" , "orgPath:LIKE") ;
	       }
	};

	@Autowired
	private PasswordEncoder passwordEncoder ;

	@Override
	public LinkedHashMap<String, String> getQueryExpressions() {
		return expressionMap ;
	}

	/**
	 * 加密密码
	 * @param plainPassword
	 * @return
	 */
	public String encodePassword( String plainPassword ){
		Assert.hasText( plainPassword , "用户密码不能为空" );

		return passwordEncoder.encode( plainPassword.trim() ) ;
	}

	/**
	 * 更新密码
	 * @param userId
	 * @param plainPassword
	 * @return
	 */
	@Transactional
	public boolean resetPassword(String userId , String plainPassword){
		SysUser sysUser = get(userId) ;
		if( sysUser!=null ){
			sysUser.setPwd( encodePassword( plainPassword ) ) ;
			this.update(sysUser , Arrays.asList("pwd") ) ;
			return true ;
		}
		return false ;
	}

	/**
	 * 根据用户编码或手机号更新密码
	 * @param userCodeOrMobile
	 * @param plainPassword
	 * @return
	 */
	@Transactional
	public boolean updatePassword(String userCodeOrMobile , String plainPassword){
		Map<String,Object> searchParams = Maps.newHashMap() ;
		searchParams.put( "code" , userCodeOrMobile.trim() ) ;
		searchParams.put( "mobile" , userCodeOrMobile.trim() ) ;

		List<SysUser> sysUsers = queryAll( searchParams ) ;

		SysUser sysUser = sysUsers!=null && sysUsers.size()>0 ? sysUsers.get(0) : null ;
		if( sysUser!=null ){
			sysUser.setPwd( encodePassword( plainPassword ) ) ;
			this.update( sysUser , Arrays.asList("pwd") ) ;
			return true ;
		}
		return false ;
	}

	/**
	 * 保存用户
	 * @param sysUser
	 * @param plainPassword
	 * @return
	 */
	@Transactional
	public SysUser saveUser( SysUser sysUser , String plainPassword ){
		if( StringUtils.isBlank(plainPassword) ){
			plainPassword = DEFAULT_PASSWORD ;
		}
		sysUser.setPwd( encodePassword(plainPassword) ) ;
		super.save( sysUser ) ;
		return sysUser ;
	}

	/**
	 * 查询是否存在指定用户的编码
	 * @param code
	 * @return
	 */
	public boolean existUserCode( String code ){
		if(StringUtils.isBlank(code)){
			return false ;
		}

		Map<String,Object> searchParams = Maps.newHashMap() ;
		searchParams.put( "code" , code.trim() ) ;

		return this.count( searchParams ) > 0 ;
	}

	public boolean existUserCode( String code , String exceptId ){
		if(StringUtils.isBlank(code)){
			return false ;
		}

		Map<String,Object> searchParams = Maps.newHashMap() ;
		searchParams.put( "code" , code.trim() ) ;

		List<String> userIds = this.entityDao.querySingleFields("id" , getQuerySpecification( searchParams )) ;
		if( userIds!=null && StringUtils.isNotBlank(exceptId)){
			userIds.remove( exceptId ) ;
		}

		return !( userIds==null || userIds.size()<1 );
	}

	public boolean existMobile( String mobile ){
		if(StringUtils.isBlank(mobile)){
			return false ;
		}

		Map<String,Object> searchParams = Maps.newHashMap() ;
		searchParams.put( "mobile" , mobile.trim() ) ;

		return this.count( searchParams ) > 0 ;
	}

	/**
	 * 判断是否存在手机号
	 * @param mobile
	 * @return
	 */
	public boolean existMobile( String mobile , String exceptId ){
		if(StringUtils.isBlank(mobile)){
			return false ;
		}

		Map<String,Object> searchParams = Maps.newHashMap() ;
		searchParams.put( "mobile" , mobile.trim() ) ;

		List<String> userIds = this.entityDao.querySingleFields("id" , getQuerySpecification( searchParams )) ;
		if( userIds!=null && StringUtils.isNotBlank(exceptId)){
			userIds.remove( exceptId ) ;
		}

		return userIds!=null && userIds.size()>0 ;
	}

	public SysUser login( String code , String plainPassword){
		if( StringUtils.isBlank(code) ){
			return null ;
		}
		Map<String,Object> searchParams = Maps.newHashMap() ;
		searchParams.put( "code" , code.trim() ) ;

		List<SysUser> sysUsers = queryAll( searchParams ) ;

		SysUser sysUser = sysUsers!=null && sysUsers.size()>0 ? sysUsers.get(0) : null ;
		//验证用户不为空、密码是否相同
		if( sysUser!=null && StringUtils.equalsIgnoreCase( sysUser.getPwd() , encodePassword( plainPassword ) ) ){
			return sysUser ;
		}

		return null ;
	}

	/**
	 * 查询用户id和姓名的映射
	 * @param ids
	 * @return
	 */
	public Map<String,String> getUserIdName(Set<String> ids){
		if(CollectionUtils.isEmpty(ids)){
			return Maps.newHashMap() ;
		}

		Map<String,Object> searchParams = Maps.newHashMap() ;
		searchParams.put("ids" , ids) ;

		List<Map<String, Object>> results = this.entityDao.queryMultiFields( new String[]{"id" , "name"} ,
				getQuerySpecification( searchParams ) ) ;

		return Maps2.toMap( results, new MapConverter<Map<String, Object>, String, String>() {
			@Override
			public String getKey(Map<String, Object> item) {
				return item.get("id").toString() ;
			}

			@Override
			public String getValue(Map<String, Object> item) {
				return item.get("name")!=null ? item.get("name").toString() : "";
			}
		}) ;
	}


}
